package com.woohua.thread.completefeature;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/***
 * @title SerialTask
 * @description： 顺序执行
 * @author woo hua
 * @version 1.0.0
 * @create 2023/3/21 9:13
 **/
public class SerialTask {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 3. thenRun : 普通顺序执行
        CompletableFuture.supplyAsync(() -> {
            System.out.println("3.1 supplyAsync begin");
            sleep(100); // 用于证明B等待A结束才会执行
            return "3.2 supplyAsync end";
        }).thenRun(() -> {
            System.out.println("3.3 thenRun be called.");
        });
        sleep(200);

        // 4. thenApply ： A返回值传递， 有返回值的顺序执行
        CompletableFuture<String> future4 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "4.1 apple";
        }).thenApply(returnVal -> {
            return "4.2 " + returnVal + "-苹果";
        });
        System.out.println("4.3 get:" + future4.get());
        sleep(100);

        // 5. thenAccept： A返回值传递， 无返回值顺序执行
        CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "5.1 orange";
        }).thenAccept(returnVal -> {
            System.out.println("5.2 " + returnVal + "-桔子");
        });
        sleep(100);

        // 6. thenCompose： A返回值传递， B异步执行，且有返回值
        CompletableFuture<String> future6 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            return "6.1 banana";
        }).thenCompose(returnVal -> {
            return CompletableFuture.supplyAsync(() -> {
                return "6.2 " + returnVal;
            });
        });

        System.out.println("6.3 get: " + future6.get());
        sleep(100);

        // 7. whenComplete：A执行完成，B获取A返回值或异常， 无返回值
        CompletableFuture.supplyAsync(() -> {
            sleep(100);
            if(true) {  // 修改boolean 值观察不同结果
                return "7.1 return value for whenComplete";
            }else {
                throw new RuntimeException("7.2 throw exception for whenComplete");
            }
        }).whenComplete((returnVal, throwable) -> {
            System.out.println("7.2 returnVal:" + returnVal);   // 可以直接拿到返回值，不需要通过future.get()得到
            System.out.println("7.3 throwable:" + throwable);   // 异步任务抛出异常，并不会因为异常终止， 而是会走到这里，后面的代码还会继续执行
        });
        sleep(100);

        // 8. exceptionally：A执行。B对A的异常处理，并返回值
        CompletableFuture<String> future8 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            if (false) { // 修改boolean 值观察不同结果
                return "8.1 return value for exceptionally";
            } else {
                throw new RuntimeException("8.2 throw exception for exceptionally");
            }
        }).exceptionally(throwable -> {
            throwable.printStackTrace();
            return "8.3 return value after dealing exception.";
        });
        System.out.println("8.4 get: " + future8.get());
        sleep(100);

        // 9.handle：A执行完成，B获取A返回值或异常，并返回值
        CompletableFuture<String> future9 = CompletableFuture.supplyAsync(() -> {
            sleep(100);
            if (true) {  // 修改boolean 值观察不同结果
                return "9.1 return value for handle";
            } else {
                throw new RuntimeException("9.2 throw exception for handle");
            }
        }).handle((returnVal, throwable) -> {
            System.out.println("9.3 returnVal: " + returnVal);
            System.out.println("9.4 throwable: " + throwable);
            return "9.5 new return value.";
        });
        System.out.println("9.6 get: " + future9.get());
        sleep(100);
    }

    private static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
